/* Author: YangSaqing
 * Last edit:2019-03-07
 *
 */

#ifndef COORD_H
#define COORD_H
#include <iostream>
#include "ttc_global.h"
/*RAE is rad
 * XYZ is m
 * */
class TTCSHARED_EXPORT CoordXYZ;//空间大地直角坐标系
class TTCSHARED_EXPORT CoordLBH;//大地坐标系，经度,纬度,海拔
class TTCSHARED_EXPORT CoordRAE;//站心极坐标系，距离，方位角（正北方向顺时针），高低角（视线与水平线）
class TTCSHARED_EXPORT CoordOXYZ;//站心直角坐标系，x：方位角0度方向（正北），y：东，z:垂直向上
class CoordLBH
{
    friend TTCSHARED_EXPORT std::ostream& operator <<(std::ostream& ostr, const CoordLBH& coord);
    friend TTCSHARED_EXPORT std::istream& operator >>(std::istream& istr, CoordLBH& coord);
public:
    /*
     * @brief: 构造函数，会设置longitude,latitude,height的值。
     * @arg: longitude 东经， 单位：rad
     *       latitude 北纬， 单位：rad
     *       height 高度： 单位: m
     */
    CoordLBH(const double &longitude = 0,const double &latitude = 0,const double &height = 0);

    //同构造函数
    void set(const double &longitude,const double &latitude,const double &height);

    //返回地心直角坐标系下坐标
    CoordXYZ toXYZ() const;

    /*
     * @brief: 转为站心极坐标系下坐标。
     * @arg: local 站址坐标。
     * @return: 站心极坐标。
     */
    CoordRAE toRAE(const CoordLBH &local) const;

    /*
     * @brief: 转为站心直角坐标系下坐标。
     * @arg: local 站址坐标。
     * @return: 站心直角坐标。
     */
    CoordOXYZ toOXYZ(const CoordLBH &local) const;

    /*
     * @brief: 重载[]运算符。
     * @arg: arg 坐标某一分量，'l'东经，’b'北纬，‘h’高度。
     * @return: 对应的longitude,latitude,height的引用。
     */
    double& operator[](const char arg);//arg: 'l','b','h'

    /*
     * @brief: 重载[]运算符。
     * @arg: arg 坐标某一分量，'l'东经，’b'北纬，‘h’高度。
     * @return: 对应的longitude,latitude,height的值。
     */
    double operator[](const char arg)const;

private:
    double longitude,latitude,height;
};

/*
 * info: 地心直角坐标系下坐标类
 */
class CoordXYZ
{
    friend TTCSHARED_EXPORT std::ostream& operator <<(std::ostream& ostr, const CoordXYZ& coord);
    friend TTCSHARED_EXPORT std::istream& operator >>(std::istream& istr, CoordXYZ& coord);
public:

    /*
     * @brief: 构造函数，初始化X,Y,Z的值。
     * @arg: X,Y,Z分别为地心直角坐标系下三坐标值，单位：米。
     */
    CoordXYZ(const double &X = 0,const double &Y = 0,const double &Z = 0);

    //同构造函数。
    void set(const double &X,const double &Y,const double &Z);

    /*
     * 返回地理坐标系下坐标
     */
    CoordLBH toLBH() const;


    //返回站心极坐标系下坐标，local为站址坐标。
    CoordRAE toRAE(const CoordLBH &local) const;

    //返回站心直角坐标，local为站址坐标。
    CoordOXYZ toOXYZ(const CoordLBH &local) const;

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'x' 'y' 'z'分别对应X Y Z三坐标值。
     * @return: 对应的 X Y Z 的引用。
     */
    double& operator[](const char arg);//arg: 'x','y','z'

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'x' 'y' 'z'分别对应X Y Z三坐标值。
     * @return: 对应的 X Y Z 的值。
     */
    double operator[](const char arg)const;

private:
    double X,Y,Z;

};

/*
 * info: 站心极坐标，以观测站为坐标原点，以该点的切平面为基准，
 *       正北为方位（A表示）0弧度，顺时针为正，
 *       视线与切平面的夹角（E表示）向上为正，
 *       R为目标点到观测点的距离
 */
class CoordRAE
{
    friend TTCSHARED_EXPORT std::ostream& operator <<(std::ostream& ostr, const CoordRAE& coord);
    friend TTCSHARED_EXPORT std::istream& operator >>(std::istream& istr, CoordRAE& coord);
public:

    /*
     * @brief: 构造函数，初始化R,A,E的值。
     * @arg: R（米）,A（弧度）,E（弧度）分别为站心极坐标系下三坐标值。
     */
    CoordRAE(const double &R = 0, const double &A = 0,const double &E = 0);
    //同构造函数。
    void set(const double &R, const double &A,const double &E);

    //转换为其它坐标，local为站址坐标
    CoordLBH toLBH(const CoordLBH &local) const;
    CoordXYZ toXYZ(const CoordLBH &local) const;
    CoordOXYZ toOXYZ() const;

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'r' 'a' 'e'分别对应 R A E 三坐标值。
     * @return: 对应的 R A E 的引用。
     */
    double& operator[](const char arg);//arg: 'r','a','e'

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'r' 'a' 'e'分别对应 R A E 三坐标值。
     * @return: 对应的 R A E 的值。
     */
    double operator[](const char arg)const;

private:
    double R,A,E;
};

/*
 * info: 站心直角坐标，主要用于站心极坐标和地心直角坐标转换的中间坐标系
 *       x：方位角0度方向（正北），y：东，z:垂直向上。
 */
class CoordOXYZ
{
    friend TTCSHARED_EXPORT std::ostream& operator <<(std::ostream& ostr, const CoordOXYZ& coord);
    friend TTCSHARED_EXPORT std::istream& operator >>(std::istream& istr, CoordOXYZ& coord);
public:
    /*
     * @brief: 构造函数，初始化X,Y,Z的值。
     * @arg: x,y,z分别为站心直角坐标系下三坐标值,单位:米
     */
    CoordOXYZ(const double &x = 0, const double &y = 0, const double &z = 0);
    //同构造函数
    void set(const double &x, const double &y, const double &z);

    //转换为其它坐标，local为站址坐标。
    CoordLBH toLBH(const CoordLBH &local) const;
    CoordXYZ toXYZ(const CoordLBH &local) const;
    CoordRAE toRAE() const;

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'x' 'y' 'z'分别对应X Y Z三坐标值。
     * @return: 对应的 X Y Z 的引用。
     */
    double& operator[](const char arg);//arg: 'x','y','z'

    /*
     * @brief: 重载 [] 运算符。
     * @arg: arg 坐标某一分量，'x' 'y' 'z'分别对应X Y Z三坐标值。
     * @return: 对应的 X Y Z 的值。
     */
    double operator[](const char arg)const;

private:
    double oX,oY,oZ;
};
#endif // COORD_H
